package com.cskaoyan.javase.object._3equals;

import com.sun.corba.se.spi.ior.ObjectKey;

/**
 * 排它性的实现有两种方式:
 *      1.getClass方法的方式
 *          这样一个排它性的校验,是比较苛刻的
 *          只有完全是同一个类型,才可以继续判断属性的取值
 *          但是像子类,父类这种继承关系,它是不关心的
 *
 *      2.更宽松一点的排它性校验方式,用instanceof
 *          引用 instanceof 类名/接口名
 *          用来判断引用所指向的对象是否是后面"类名/接口名"的对象,或者子类对象(如果是抽象类和接口,只能是子类对象)
 *          如果是,则返回true,否则返回false
 *          如果引用是null,无条件返回false
 *
 * 总结:
 *      getClass实现的排它性,更严格,但也更普遍,更常用
 *      instanceof实现的排它性,允许传入子类对象,更宽松,但总的来说,比较少见,了解知道就可以了
 *
 * @since 14:42
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo2 {
    public static void main(String[] args) {
        Teacher t = new Teacher(18);
        TeacherSon ts = new TeacherSon(18);
        System.out.println(t == ts);
        System.out.println(t.equals(ts));
    }
}

class Teacher {
    int age;
    String name;

    public Teacher(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Teacher)) return false;

        Teacher teacher = (Teacher) o;

        if (age != teacher.age) return false;
        return name != null ? name.equals(teacher.name) : teacher.name == null;
    }

    @Override
    public int hashCode() {
        int result = age;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
    /*@Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        *//*if (obj == null || this.getClass() != obj.getClass()) {
            return false;
        }*//*
        if (!(obj instanceof Teacher)) {
            return false;
        }
        Teacher t = (Teacher) obj;
        return age == t.age;
    }*/
}

// 思考: 如果用instanceof实现排它性,允许传入子类对象,那么后续的对称性,传递性等的实现,有没有变化呢? 要没要特殊要求呢?
class TeacherSon extends Teacher {
    public TeacherSon(int age) {
        super(age);
    }
}